home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 21
/
Cream of the Crop 21 (Terry Blount) (October 1996).iso
/
os2
/
e33el2.zip
/
emacs
/
19.33
/
lisp
/
decipher.el
< prev
next >
Wrap
Lisp/Scheme
|
1996-08-04
|
44KB
|
1,052 lines
;;; decipher.el --- Cryptanalyze monoalphabetic substitution ciphers
;;
;; Copyright (C) 1995, 1996 Free Software Foundation, Inc.
;;
;; Author: Christopher J. Madsen <ac608@yfn.ysu.edu>
;; Keywords: games
;;
;; This file is part of GNU Emacs.
;;
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;;
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Quick Start:
;;
;; To decipher a message, type or load it into a buffer and type
;; `M-x decipher'. This will format the buffer and place it into
;; Decipher mode. You can save your work to a file with the normal
;; Emacs save commands; when you reload the file it will automatically
;; enter Decipher mode.
;;
;; I'm not going to discuss how to go about breaking a cipher; try
;; your local library for a book on cryptanalysis. One book you might
;; find is:
;; Cryptanalysis: A study of ciphers and their solution
;; Helen Fouche Gaines
;; ISBN 0-486-20097-3
;;; Commentary:
;;
;; This package is designed to help you crack simple substitution
;; ciphers where one letter stands for another. It works for ciphers
;; with or without word divisions. (You must set the variable
;; decipher-ignore-spaces for ciphers without word divisions.)
;;
;; First, some quick definitions:
;; ciphertext The encrypted message (what you start with)
;; plaintext The decrypted message (what you are trying to get)
;;
;; Decipher mode displays ciphertext in uppercase and plaintext in
;; lowercase. You must enter the plaintext in lowercase; uppercase
;; letters are interpreted as commands. The ciphertext may be entered
;; in mixed case; `M-x decipher' will convert it to uppercase.
;;
;; Decipher mode depends on special characters in the first column of
;; each line. The command `M-x decipher' inserts these characters for
;; you. The characters and their meanings are:
;; ( The plaintext & ciphertext alphabets on the first line
;; ) The ciphertext & plaintext alphabets on the second line
;; : A line of ciphertext (with plaintext below)
;; > A line of plaintext (with ciphertext above)
;; % A comment
;; Each line in the buffer MUST begin with one of these characters (or
;; be left blank). In addition, comments beginning with `%!' are reserved
;; for checkpoints; see decipher-make-checkpoint & decipher-restore-checkpoint
;; for more information.
;;
;; While the cipher message may contain digits or punctuation, Decipher
;; mode will ignore these characters.
;;
;; The buffer is made read-only so it can't be modified by normal
;; Emacs commands.
;;
;; Decipher supports Font Lock mode. To use it, you can also add
;; (add-hook 'decipher-mode-hook 'turn-on-font-lock)
;; See the variable `decipher-font-lock-keywords' if you want to customize
;; the faces used. I'd like to thank Simon Marshall for his help in making
;; Decipher work well with Font Lock.
;;; Things To Do:
;;
;; Email me if you have any suggestions or would like to help.
;; But be aware that I work on Decipher only sporadically.
;;
;; 1. The consonant-line shortcut
;; 2. More functions for analyzing ciphertext
;;;===================================================================
;;; Variables:
;;;===================================================================
(eval-when-compile
(require 'cl))
(defvar decipher-force-uppercase t
"*Non-nil means to convert ciphertext to uppercase.
Nil means the case of the ciphertext is preserved.
This variable must be set before typing `\\[decipher]'.")
(defvar decipher-ignore-spaces nil
"*Non-nil means to ignore spaces and punctuation when counting digrams.
You should set this to `nil' if the cipher message is divided into words,
or `t' if it is not.
This variable is buffer-local.")
(make-variable-buffer-local 'decipher-ignore-spaces)
(defvar decipher-undo-limit 5000
"The maximum number of entries in the undo list.
When the undo list exceeds this number, 100 entries are deleted from
the tail of the list.")
;; End of user modifiable variables
;;--------------------------------------------------------------------
(defvar decipher-font-lock-keywords
'(("^:.*" . font-lock-keyword-face)
("^>.*" . font-lock-string-face)
("^%!.*" . font-lock-reference-face)
("^%.*" . font-lock-comment-face)
("\\`(\\([a-z]+\\) +\\([A-Z]+\\)"
(1 font-lock-string-face)
(2 font-lock-keyword-face))
("^)\\([A-Z ]+\\)\\([a-z ]+\\)"
(1 font-lock-keyword-face)
(2 font-lock-string-face)))
"Expressions to fontify in Decipher mode.
Ciphertext uses `font-lock-keyword-face', plaintext uses
`font-lock-string-face', comments use `font-lock-comment-face', and
checkpoints use `font-lock-reference-face'. You can customize the
display by changing these variables. For best results, I recommend
that all faces use the same background color.
For example, to display ciphertext in the `bold' face, use
(add-hook 'decipher-mode-hook
(lambda () (set (make-local-variable 'font-lock-keyword-face)
'bold)))
in your `.emacs' file.")
(defvar decipher-mode-map nil
"Keymap for Decipher mode.")
(if (not decipher-mode-map)
(progn
(setq decipher-mode-map (make-keymap))
(suppress-keymap decipher-mode-map)
(define-key decipher-mode-map "A" 'decipher-show-alphabet)
(define-key decipher-mode-map "C" 'decipher-complete-alphabet)
(define-key decipher-mode-map "D" 'decipher-digram-list)
(define-key decipher-mode-map "F" 'decipher-frequency-count)
(define-key decipher-mode-map "M" 'decipher-make-checkpoint)
(define-key decipher-mode-map "N" 'decipher-adjacency-list)
(define-key decipher-mode-map "R" 'decipher-restore-checkpoint)
(define-key decipher-mode-map "U" 'decipher-undo)
(define-key decipher-mode-map " " 'decipher-keypress)
(substitute-key-definition 'undo 'decipher-undo
decipher-mode-map global-map)
(substitute-key-definition 'advertised-undo 'decipher-undo
decipher-mode-map global-map)
(let ((key ?a))
(while (<= key ?z)
(define-key decipher-mode-map (vector key) 'decipher-keypress)
(incf key)))))
(defvar decipher-stats-mode-map nil
"Keymap for Decipher-Stats mode.")
(if (not decipher-stats-mode-map)
(progn
(setq decipher-stats-mode-map (make-keymap))
(suppress-keymap decipher-stats-mode-map)
(define-key decipher-stats-mode-map "D" 'decipher-digram-list)
(define-key decipher-stats-mode-map "F" 'decipher-frequency-count)
(define-key decipher-stats-mode-map "N" 'decipher-adjacency-list)
))
(defvar decipher-mode-syntax-table nil
"Decipher mode syntax table")
(if decipher-mode-syntax-table
()
(let ((table (make-syntax-table))
(c ?0))
(while (<= c ?9)
(modify-syntax-entry c "_" table) ;Digits are not part of words
(incf c))
(setq decipher-mode-syntax-table table)))
(defvar decipher-alphabet nil)
;; This is an alist containing entries (PLAIN-CHAR . CIPHER-CHAR),
;; where PLAIN-CHAR runs from ?a to ?z and CIPHER-CHAR is an uppercase
;; letter or space (which means no mapping is known for that letter).
;; This *must* contain entries for all lowercase characters.
(make-variable-buffer-local 'decipher-alphabet)
(defvar decipher-stats-buffer nil
"The buffer which displays statistics for thi